package  com.hadron.ui.scroll.behaviors {
	import com.hadron.ui.scroll.Scrollbar;
	import com.hadron.ui.scroll.events.ScrollbarEvent;
	import flash.display.StageQuality;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import temple.behaviors.AbstractBehavior;
	import temple.utils.StageProvider;	

	/**
	 * ...
	 * @author Hadron
	 */
	public class ScrollbarBehavior extends AbstractBehavior implements IScrollbarBehavior 
	{
		/** @private */
		private var _debug:Boolean = false;
		/**
		 * 
		 * @param	target 
		 */
		public function ScrollbarBehavior(target:Object) 
		{
			super(target);
			init();
		}
		/**
		 * Inits behavior, sets default listeners on object
		 * @private
		 */
		private function init():void 
		{
			//configure default event listeners
			scrollBar.addEventListener(Event.ADDED_TO_STAGE, handleAdd);
			scrollBar.addEventListener(Event.REMOVED_FROM_STAGE, handleRemove);
			scrollBar.thumb.addEventListener(MouseEvent.MOUSE_DOWN, handleThumbDown);
			scrollBar.track.addEventListener(MouseEvent.CLICK, handleTrackClick);
		}
		/*------------------------------------------ PUBLIC METHODS --------------------------------------------*/
		/**
		 * @inheritDoc
		 */
		override public function destruct():void
		{
			if (scrollBar)
			{
				scrollBar.removeEventListener(Event.ADDED_TO_STAGE, handleAdd);
				scrollBar.removeEventListener(Event.REMOVED_FROM_STAGE, handleRemove);
				scrollBar.thumb.removeEventListener(MouseEvent.MOUSE_DOWN, handleThumbDown);
				scrollBar.track.removeEventListener(MouseEvent.CLICK, handleTrackClick);
				StageProvider.stage.removeEventListener(MouseEvent.MOUSE_UP, handleThumbUp);
				StageProvider.stage.removeEventListener(MouseEvent.MOUSE_WHEEL, handleMouseWheel);
			}
			super.destruct();
		}
		/*------------------------------------------ GETTERS & SETTERS -----------------------------------------*/
		/* INTERFACE com.hadron.ui.scroll.interfaces.IScrollbarBehavior */
		public function get scrollBar():Scrollbar { return target as Scrollbar;	}
		public function get debug():Boolean { return _debug; }
		public function set debug(value:Boolean):void { _debug = value; }
		
		/*------------------------------------------ EVENT HANDLERS --------------------------------------------*/
		/**
		 * Handles default Event.ADDED_TO_STAGE
		 * @private	event
		 */
		protected function handleAdd(event:Event):void 
		{
			//removeEventListener(Event.ADDED_TO_STAGE, handleAdd);
			StageProvider.stage.addEventListener(MouseEvent.MOUSE_UP, handleThumbUp);
			StageProvider.stage.addEventListener(MouseEvent.MOUSE_WHEEL, handleMouseWheel);
		}
		/**
		 * Handles default Event.REMOVED_FROM_STAGE
		 * @private	event
		 */
		protected function handleRemove(event:Event):void 
		{
			//removeEventListener(Event.REMOVED_FROM_STAGE, handleRemove);
			StageProvider.stage.removeEventListener(MouseEvent.MOUSE_UP, handleThumbUp);
			StageProvider.stage.removeEventListener(MouseEvent.MOUSE_WHEEL, handleMouseWheel);
		}
		/**
		 * Handles track Mouse.CLICK event
		 * @private	event
		 */
		protected function handleTrackClick(event:MouseEvent):void 
		{
			var localPoint:Point = new Point(StageProvider.stage.mouseX, StageProvider.stage.mouseY);
			scrollBar.calculatePercentagePosition(scrollBar.globalToLocal(localPoint).y);
		}
		/**
		 * Handles MouseEvent.MOUSE_WHEEL while mouse is over the object
		 * @private	event
		 */
		protected function handleMouseWheel(event:MouseEvent):void 
		{	
			if (scrollBar.isMouseOver && scrollBar.visible) 
			{
				if (event.delta < 0) 
				{
					if (scrollBar.thumb.y < scrollBar.yMax) 
					{
						scrollBar.thumb.y -= (event.delta * 7);
						if (scrollBar.thumb.y > scrollBar.yMax) 
							scrollBar.thumb.y = scrollBar.yMax;						
					}
				} else {
					if (scrollBar.thumb.y > scrollBar.yMin) 
					{
						scrollBar.thumb.y -= (event.delta * 7);
						if (scrollBar.thumb.y < scrollBar.yMin) 
							scrollBar.thumb.y = scrollBar.yMin;
					}
				}
				scrollBar.dispatchEvent(new ScrollbarEvent(scrollBar.thumb.y / scrollBar.yMax));
			}
		}
		/**
		 * Handles MouseEvent.MOUSE_DOWN on thumb
		 * @private	event
		 */
		protected function handleThumbDown(event:MouseEvent):void
		{
			StageProvider.stage.addEventListener(MouseEvent.MOUSE_MOVE, handleThumbMove);
			scrollBar.distance = scrollBar.mouseY - scrollBar.thumb.y;
			if (scrollBar.changeStageQuality) 
				StageProvider.stage.quality = StageQuality.MEDIUM;
		}
		/**
		 * Handles MouseEvent.MOUSE_UP on thumb
		 * @private	event
		 */
		protected function handleThumbUp(event:MouseEvent):void
		{
			StageProvider.stage.removeEventListener(MouseEvent.MOUSE_MOVE, handleThumbMove);
			if (scrollBar.changeStageQuality) 
				StageProvider.stage.quality = StageQuality.HIGH;
		}
		/**
		 * Handlers MouseEvent.MOUSE_MOVE while dragging thumb
		 * @private	event
		 */
		protected function handleThumbMove(event:MouseEvent):void 
		{	
			scrollBar.thumb.y = scrollBar.mouseY - scrollBar.distance;
			if (scrollBar.thumb.y <= scrollBar.yMin)
				scrollBar.thumb.y = scrollBar.yMin;
			if (scrollBar.thumb.y >= scrollBar.yMax)
				scrollBar.thumb.y = scrollBar.yMax;
				
			scrollBar.dispatchEvent(new ScrollbarEvent(scrollBar.thumb.y / scrollBar.yMax));
			event.updateAfterEvent();
		}
	}
}